#include "Pch.h"
#include "SharedStatusBar.h"
#include "PDBManager.h"

BEGIN_EVENT_TABLE(SharedStatusBar, wxStatusBar)
	EVT_SIZE(SharedStatusBar::OnSize)
END_EVENT_TABLE()

SharedStatusBar::SharedStatusBar(wxWindow *parent, PDBManager *pdbManager) : wxStatusBar(parent, wxID_ANY, wxST_SIZEGRIP | wxST_DOTS_END) {
	this->pdbManager = pdbManager;
	type = STATUS_TEXT;
	flags = 0;
	statusUpdate = 0;
	PlaceFields();
	lastCount = 0;
}

void SharedStatusBar::OnSize(wxSizeEvent& evt) {
	PlaceFields();
}

void SharedStatusBar::PlaceFields() {
	int width = GetClientSize().GetWidth();
	int widths[] = {
		150, 150, 85, 37, 62, 80
	};
	for (int i=1; i<sizeof(widths)/sizeof(int); i++) {
		width -= widths[i];
	}
	if (width < 100) width = 100;
	widths[0] = width;
	SetFieldsCount(sizeof(widths)/sizeof(int), widths);
	type = STATUS_RESIDUE;
	int styles[] = {
		wxSB_NORMAL,
		wxSB_FLAT,
		wxSB_NORMAL,
		wxSB_FLAT,
		wxSB_NORMAL,
		wxSB_NORMAL,
	};
	SetStatusStyles(sizeof(widths)/sizeof(int), styles);
}

void SharedStatusBar::SetText(const wxString &string) {
	if (flags & STATUS_BAR_LOCKED) return;
	//SetFieldsCount(1);
	SetStatusText(string);
	type = STATUS_TEXT;
	statusUpdate = 1;
}

void SharedStatusBar::LockText(const wxString &string) {
	UnlockText();
	SetText(string);
	flags |= STATUS_BAR_LOCKED;
	statusUpdate = 1;
}

void SharedStatusBar::UnlockText() {
	flags &= ~STATUS_BAR_LOCKED;
}

void SharedStatusBar::UpdatePDB(PDBManager *manager) {
	pdbManager = manager;
	// Should always be locked here, anyways.
	SetText(wxEmptyString);
	SetResidue(-1, -1);
}

void SharedStatusBar::SetResidue(int chainId, int residue) {
	if (!(flags & STATUS_BAR_LOCKED) && (type == STATUS_RESIDUE || chainId >= 0)) {
		type = STATUS_RESIDUE;
		UpdateSelectionCount();
	}
	int base = 1;
	if (chainId != -1) {
		ManagedChain *chain = pdbManager->chains[chainId];
		PDBResidue *res = &chain->residues[residue];
		SetStatusText(wxString(chain->idString, wxMBConvUTF7(), strlen(chain->idString)), base);
		SetStatusText(wxString::Format(_T("%i AA"), chain->numChainResidues), base+1);
		SetStatusText(wxString(res->resName, wxMBConvUTF7(), strlen(res->resName)), base+2);
		if (res->resNum != PDB_ID_NONE)
			SetStatusText(wxString::Format(_T("%i%c"), res->resNum, res->resLetter), base+3);
		else
			SetStatusText(wxEmptyString, base+3);

		int numAtoms = res->lastAtom+1-res->firstAtom;
		if (res->firstAtom < 0) numAtoms = 0;
		wxString s = wxString::Format(_T("%i atom"), numAtoms);
		if (numAtoms != 1) s.Append(_T("s"));
		SetStatusText(s, base+4);
	}
	else {
		for (int i=0; i<5; i++) {
			SetStatusText(wxEmptyString, base+i);
		}
	}
}

void SharedStatusBar::UpdateSelectionCount() {
	if (flags & STATUS_BAR_LOCKED) return;
	int count = 0;
	for (int c=0; c<pdbManager->numChains; c++) {
		ManagedChain *chain = pdbManager->chains[c];
		for (int r=0; r<chain->numTotalResidues; r++) {
			if (chain->residueInfo[r].flags & (RESIDUE_SELECTED | RESIDUE_LAST_SELECTED)) count++;
		}
	}
	if (!statusUpdate || (count > 0 && lastCount != count)) {
		statusUpdate = 0;
		if (count != 1)
			SetStatusText(wxString::Format(_T("%i residues selected"), count), 0);
		else
			SetStatusText(_T("1 residue selected"), 0);
	}
}
